﻿using HMEngine.HMComponents;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace HMEngine.HMEffects {
    public sealed class HMPostProcessor : HMEffect, IHMPostProcessable {
        private VertexPositionTexture[] verts;
        private ResolveTexture2D ResolvedTexture { get; set; }
        private VertexDeclaration VertexDeclaration { get; set; }

        public HMPostProcessor(string asset) : base(asset) { }

        private void LoadResolveTarget(GraphicsDevice myDevice) {
            ResolvedTexture = new ResolveTexture2D(
                myDevice, myDevice.Viewport.Width,
                myDevice.Viewport.Height, 1,
                myDevice.DisplayMode.Format
                );
        }

        public override void LoadContent(GraphicsDevice myDevice, ContentManager myLoader) {
            base.LoadContent(myDevice, myLoader);

            verts = new[] {
                new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)),
                new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0)),
                new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)),
                new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0))
            };

            VertexDeclaration = new VertexDeclaration(myDevice, VertexPositionTexture.VertexElements);

            LoadResolveTarget(myDevice);
        }

        public void PostProcess(GraphicsDevice myDevice) {
            if (
                ResolvedTexture.Width != myDevice.Viewport.Width ||
                ResolvedTexture.Height != myDevice.Viewport.Height ||
                ResolvedTexture.Format != myDevice.DisplayMode.Format
                ) {
                LoadResolveTarget(myDevice);
            }

            myDevice.ResolveBackBuffer(ResolvedTexture);
            myDevice.Textures[0] = ResolvedTexture;

            Effect.Begin();
            foreach (EffectPass pass in Effect.CurrentTechnique.Passes) {
                pass.Begin();
                myDevice.VertexDeclaration = VertexDeclaration;
                myDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, verts, 0, 2);
                pass.End();
            }
            Effect.End();

            HMEffectManager.ScreenTexture = ResolvedTexture;
        }
    }
}